package cc.yugu.yhdw.webserver.service.hdw;

import cc.yugu.yhdw.common.constant.ConstEnum;
import cc.yugu.yhdw.common.domain.basic.AgentInOutMoney;
import cc.yugu.yhdw.common.domain.basic.PlatformInOutMoney;
import cc.yugu.yhdw.common.domain.hdw.*;
import cc.yugu.yhdw.common.entity.pagination.Page;
import cc.yugu.yhdw.common.entity.tree.Node;
import cc.yugu.yhdw.common.entity.tree.NodeModel;
import cc.yugu.yhdw.common.utils.YhdwUtils;
import cc.yugu.yhdw.webserver.persistence.basic.*;
import cc.yugu.yhdw.webserver.persistence.hdw.*;
import cc.yugu.yhdw.webserver.service.AbstractService;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.JsonEncoding;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 换电订单业务
 *
 * @Date:Created in 2018/7/9 10:18
 * @Author:
 * @Modified By: zjn 2018/7/9 10:18
 */
@Service
public class ExchangeOrderService extends AbstractService {
    @Autowired
    ExchangeOrderMapper exchangeOrderMapper;
    @Autowired
    PassportMapper passportMapper;
    @Autowired
    CabinetBoxMapper cabinetBoxMapper;
    @Autowired
    CabinetMapper cabinetMapper;
    @Autowired
    CommonOrderMapper commonOrderMapper;
    @Autowired
    BatteryMapper batteryMapper;
    @Autowired
    BatteryPackMapper batteryPackMapper;
    @Autowired
    ExchangeAmountMoneyDivideDetailMapper exchangeAmountMoneyDivideDetailMapper;
    @Autowired
    ExchangeOrderMoneyDivideMapper exchangeOrderMoneyDivideMapper;
    @Autowired
    AgentMapper agentMapper;
    @Autowired
    AgencyMapper agencyMapper;
    @Autowired
    SupplierMapper supplierMapper;
    @Autowired
    PlatformMapper platformMapper;
    @Autowired
    PlatformInOutMoneyMapper platformInOutMoneyMapper;
    @Autowired
    AgentInOutMoneyMapper agentInOutMoneyMapper;
    @Autowired
    AgencyInOutMoneyMapper agencyInOutMoneyMapper;
    @Autowired
    SupplierInOutMoneyMapper supplierInOutMoneyMapper;
    @Autowired
    ExchangePacketOrderMapper exchangePacketOrderMapper;

    /**
     * 查询
     *
     * @Param: [id]
     * @Return: cc.yugu.yhdw.common.domain.hdw.ExchangeOrder
     * @Author By: zjn 2018/7/9  10:18
     */
    public ExchangeOrder find(String id) {
        return exchangeOrderMapper.find(id);
    }

    /**
     * 分页查询
     *
     * @Param: [search]
     * @Return: cc.yugu.yhdw.common.entity.pagination.Page
     * @Author By: zjn 2018/7/9  10:19
     */
    public Page findPage(ExchangeOrder search) {
        Page page = search.buildPage();
        page.setTotalItems(exchangeOrderMapper.findPageCount(search));
        search.setBeginIndex(page.getOffset());
        page.setResult(exchangeOrderMapper.findPageResult(search));
        return page;
    }

    /**
     * （该方法没有用到）
     *
     * @Param: [stream]
     * @Return: void
     * @Author By: zjn 2018/7/9  10:19
     */
    public void monthTree(OutputStream stream) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        JsonGenerator json = objectMapper.getJsonFactory().createJsonGenerator(stream, JsonEncoding.UTF8);
        json.writeStartArray();
        YhdwUtils.writeJson(buildTree(), json);
        json.writeEndArray();

        json.flush();
        json.close();
    }

    private List<Node<NodeModel>> buildTree() {
        // 取出不重复的时间 ：年
        List<String> yearList = exchangeOrderMapper.findYeah();
        // 取出不重复的时间 ：年、月
        List<Map<String, String>> monthMap = exchangeOrderMapper.findMonth();
        List<Node<NodeModel>> roots = new ArrayList<Node<NodeModel>>();
        for (String year : yearList) {
            NodeModel nodeModel = new NodeModel();
            Node<NodeModel> node = new Node<NodeModel>(nodeModel);

            nodeModel.setId(year);
            nodeModel.setName(year);
            nodeModel.setCheckStatus(NodeModel.CheckedStatus.unchecked);
            for (Map<String, String> map : monthMap) {
                if (map.get("yeah").equals(year)) {
                    NodeModel nodeModel2 = new NodeModel();
                    Node<NodeModel> node2 = new Node<NodeModel>(nodeModel2);
                    nodeModel2.setId(year + map.get("month"));
                    nodeModel2.setName(map.get("month"));
                    nodeModel2.setCheckStatus(NodeModel.CheckedStatus.unchecked);
                    node.addChild(node2);
                }
            }
            roots.add(node);
        }
        return roots;
    }

    /**
     * 换电记录数据更新
     *
     * @Param: [id, cabinetId, secondBoxNum]
     * @Return: int
     * @Author By: zjn 2018/7/9  13:30
     */
    @Transactional(rollbackFor = Throwable.class)
    public int complete(String id, String cabinetId, String secondBoxNum) {
        // 根据柜子id和箱号查询
        CabinetBox box = cabinetBoxMapper.find(cabinetId, secondBoxNum);
        // 根据主键查询
        ExchangeOrder exchangeOrder = exchangeOrderMapper.find(id);
        // 按主键更新
        int effect = exchangeOrderMapper.takeSecondBattery(id, ExchangeOrder.OrderStatus.COMPLETE.getValue(), secondBoxNum, new Date(), box.getBatteryId());
        if (effect > 0) {
            commonOrderMapper.updateOrderStatus(id, CommonOrder.OrderStatus.COMPLETE.getValue());
            batteryMapper.cleanCustomerId(exchangeOrder.getFirstBatteryId());
            batteryMapper.updateOrderId(box.getBatteryId(), Battery.Status.BUSY.getValue(), id, exchangeOrder.getCustomerId());
            passportMapper.updateBattery(exchangeOrder.getCustomerId(), box.getBatteryId());
            Battery battery = batteryMapper.find(box.getBatteryId());
            batteryPackMapper.addExchangeAmount(battery.getPackId());
            Cabinet cabinet = cabinetMapper.find(cabinetId);

            if (StringUtils.isNotEmpty(exchangeOrder.getExchangePacketOrderId())) {
                ExchangePacketOrder exchangePacketOrder = exchangePacketOrderMapper.find(exchangeOrder.getExchangePacketOrderId());
                if (exchangePacketOrder.getType() == ExchangePacket.Type.CODE_1.getValue()) {
                    exchangePacketOrderMapper.updateSurplusNumber(exchangePacketOrder.getId());
                    if (exchangePacketOrder.getSurplusNumber() - 1 <= 0) {
                        exchangePacketOrderMapper.updateExpiredOrder(ExchangePacketOrder.Status.USED.getValue(), ExchangePacketOrder.Status.EXPIRED.getValue(), new Date(), exchangePacketOrder.getId());
                    }
                }
            } else if (exchangeOrder.getPayType() != ConstEnum.PayType.PACKET.getValue() && cabinet != null && cabinet.getDividePlanId() != null) {
                List<ExchangeAmountMoneyDivideDetail> list = exchangeAmountMoneyDivideDetailMapper.findByAmount(battery.getExchangeAmount() + 1, cabinet.getDividePlanId());
                int i = 0;
                for (ExchangeAmountMoneyDivideDetail e : list) {
                    ExchangeOrderMoneyDivide exchangeOrderMoneyDivide = new ExchangeOrderMoneyDivide();
                    exchangeOrderMoneyDivide.setOrderId(id);
                    exchangeOrderMoneyDivide.setNum(++i);
                    exchangeOrderMoneyDivide.setAmount(battery.getExchangeAmount());
                    exchangeOrderMoneyDivide.setOrgType(e.getOrgType());
                    exchangeOrderMoneyDivide.setOrgId(e.getOrgId());
                    int money = (Math.abs(exchangeOrder.getMoneyCharge()) + Math.abs(exchangeOrder.getExchangeCharge())) * e.getPercent() / 100;
                    exchangeOrderMoneyDivide.setMoney(money);
                    exchangeOrderMoneyDivideMapper.create(exchangeOrderMoneyDivide);
                    if (e.getOrgType() == ExchangeAmountMoneyDivideDetail.OrgType.HQ.getValue()) {
                        platformMapper.updateBalance(e.getOrgId(), money);
                        platformInOutMoneyMapper.insert(new PlatformInOutMoney(e.getOrgId(), money, PlatformInOutMoney.BizType.CHARGE_INCOME.getValue(), id, new Date()));
                    } else if (e.getOrgType() == ExchangeAmountMoneyDivideDetail.OrgType.AGENT.getValue()) {
                        agentMapper.updateBalance(e.getOrgId(), money);
                        agentInOutMoneyMapper.insert(new AgentInOutMoney(e.getOrgId(), money, AgentInOutMoney.BizType.CHARGE_INCOME.getValue(), id, new Date()));
                    } else if (e.getOrgType() == ExchangeAmountMoneyDivideDetail.OrgType.AGENCY.getValue()) {
                        agencyMapper.updateBalance(e.getOrgId(), money);
                        agencyInOutMoneyMapper.insert(new AgencyInOutMoney(e.getOrgId(), money, AgencyInOutMoney.BizType.CHARGE_INCOME.getValue(), id, new Date()));
                    } else {
                        supplierMapper.updateBalance(e.getOrgId(), money);
                        supplierInOutMoneyMapper.insert(new SupplierInOutMoney(e.getOrgId(), money, SupplierInOutMoney.BizType.CHARGE_INCOME.getValue(), id, new Date()));
                    }
                }
            }
        }
        return effect;
    }

    /**
     * 根据订单属性获取订单id列表
     *
     * @Param
     * @Return
     * @Author zxj 2018/7/24
     */
    public List<String> findOrderIds(ExchangeOrder exchangeOrder) {
        return exchangeOrderMapper.findOrderIds(exchangeOrder);
    }

}
